package com.DynamicCompile;

import com.sun.corba.se.spi.orbutil.fsm.Input;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.*;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

/**
 * 动态编译
 * 使用
 * @author jiangbang
 * @date 2016/9/20
 */
public class Demo01 {
    public static void main(String[] args) throws IOException {
        test3();
    }
    public static void test1() throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        int result = compiler.run(null,null,null,"D:/hello.java","D:/hello1.java");
        System.out.println(result==0?"编译成功":"编译失败");

        //通过IO流操作，将一个字符串存储为一个临时文件（HI.java）,然后调用动态编译方法！
        String src = "public class HI{public static void main(String[] args){ System.out.println(\"编译成功\")}}";
        byte[] buyffer = src.getBytes();
        //创建临时文件
        File fTemp = File.createTempFile("HI", ".java", new File("D:\\"));
        //当虚拟机退出时，删除此临时java源文件
        fTemp.deleteOnExit();
        FileOutputStream outputStream = new FileOutputStream(fTemp);
        outputStream.write(buyffer,0,buyffer.length);
        outputStream.flush();
        int result2 = compiler.run(null,null,null,fTemp.getAbsolutePath());
        System.out.println(result2==0?"编译成功":"编译失败");
        outputStream.close();
    }
    public static void test2() throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        int result = compiler.run(null,null,null,"D:/hello.java");
        System.out.println(result==0?"编译成功":"编译失败");

        //执行编译文件
        Runtime run = Runtime.getRuntime();
        Process process = run.exec("java -cp D:/ hello");
        InputStream in = process.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
        String info = "";
        while((info=reader.readLine())!=null){
            System.out.println(info);
        }
    }

    //通过反射调用
    public static void test3() throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        int result = compiler.run(null,null,null,"D:/hello.java");
        System.out.println(result==0?"编译成功":"编译失败");

        try {
            URL[] urls = new URL[] {new URL("file:/"+"D:/")};
            URLClassLoader loader = new URLClassLoader(urls);
            Class c = loader.loadClass("hello");
            //调用加载类的main方法
            Method m = c.getMethod("main",String[].class);
            m.invoke(null, (Object)new String[]{});
            //由于可变参数是JDK5.0之后才有。
            //m.invoke(null, (Object)new String[]{});会编译成:m.invoke(null,"aa","bb"),就发生了参数个数不匹配的问题。
            //因此，必须要加上(Object)转型，避免这个问题。
            //public static void main(String[] args)

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
